1、 pinctrl 子系统功能
	pinctrl 子系统即引脚配置子系统，它从设备树获取引脚配置信息，并完成对引脚复用功能和电气特性的配置
2、 stm32 pinctrl 节点简介
	stm32mp157 有两个 pinctrl 控制器节点: pinctrl: pin-controller@50002000 和 pinctrl_z: pin-controller-z@54
004000 ， pinctrl: pin-controller@50002000 节点描述的是 GPIOA~K 的引脚复用功能和电气特性， pinctrl_z: pin-co
ntroller-z@54004000 的是 GPIOZ 的引脚复用功能和电气特性，两个节点基本相似，如下是 pinctrl: pin-controller@50
002000 展开后的内容：
	pinctrl: pin-controller@50002000 {
		#address-cells = <1>;					//表示 pinctrl 中 reg 属性的地址为长度为32位
		#size-cells = <1>;						//表示 pinctrl 中 reg 属性的地址范围为长度为32位
		compatible = "st,stm32mp157-pinctrl";	//驱动匹配名称
		ranges = <0 0x50002000 0xa400>;			//地址范围映射，PA~PK 这 11 组 GPIO 的寄存器都在一起，其
												//起始地址为 0X50002000，终止地址为0X5000C3FF
		interrupt-parent = <&exti>;				//表示父中断控制器位exti
		st,syscfg = <&exti 0x60 0xff>;
		hwlocks = <&hsem 0 1>;
		pins-are-numbered;
	
		gpioa: gpio@50002000 {
			gpio-controller;			//表示此节点是一个GPIO控制器
			#gpio-cells = <2>;			//表示引用此GPIO节点时要传递2个参数
			interrupt-controller;		//表示此节点是一个中断控制器
			#interrupt-cells = <2>;		//表示使用此中断控制器时需要传递两个参数
			reg = <0x0 0x400>;			// GPIOA 控制器的寄存器基地址偏移为 0X400
			clocks = <&rcc GPIOA>;		//clocks 属性指定这个 GPIOA 控制器的时钟。
			st,bank-name = "GPIOA";
			status = "disabled";
		};
	
		......
	
		gpiok: gpio@5000c000 {
			gpio-controller;
			#gpio-cells = <2>;
			interrupt-controller;
			#interrupt-cells = <2>;
			reg = <0xa000 0x400>;
			clocks = <&rcc GPIOK>;
			st,bank-name = "GPIOK";
			status = "disabled";
		};
	
		//一组配置节点节点可以由多个 pins 组成
		m_can1_pins_a: m-can1-0 {
			pins1 {
				//一个 pins 可以描述多个引脚，但是只能使用相同的电气特性
				pinmux = <STM32_PINMUX('H', 13, AF9)>;	//配置引脚互用功能，参考 “STM32MP157A&D 数据手册”
				//引脚电器特性:
				//	bias-disable		bootlean		禁止使用內部偏置电压
				//	bias-pull-down		bootlean		内部下拉
				//	bias-pull-up		bootlean		内部上拉
				//	drive-push-pull		bootlean		推挽输出
				//	drive-open-drain	bootlean		开漏输出
				//	output-low			bootlean		输出低电平
				//	output-high			bootlean		输出高电平
				//	slew-rate			enum			引脚的速度，可设置： 0~3， 0 最慢， 3 最高
				slew-rate = <1>;
				drive-push-pull;
				bias-disable;
			};
			//
			pins2 {
				pinmux = <STM32_PINMUX('I', 9, AF9)>; /* CAN1_RX */
				bias-disable;
			};
		};
	
		m_can1_sleep_pins_a: m_can1-sleep-0 {
			pins {
				pinmux = <STM32_PINMUX('H', 13, ANALOG)>, /* CAN1_TX */
					<STM32_PINMUX('I', 9, ANALOG)>; /* CAN1_RX */
			};
		};
	
		......
	};
3、使用 pinctrl 子系统
	1）添加引脚配置节点
		在根节点外通过 &pinctrl 引用 pinctrl: pin-controller@50002000 节点，或通过 pinctrl_z 引用pinctrl_z: p
	in-controller-z@54004000 节点，然后在内部添加或修改相应的引脚配置节点，如下是在 pinctrl: pin-controller@5
	0002000 添加一个出口引脚复用的配置节点：
		&pinctrl {
			//添加一个名字为 uart4_pins 的节点来描述 uart4 的引脚复用信息
			uart4_pins_a: uart4-0 {
				pins1 {
					pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
					bias-disable;
					drive-push-pull;
					slew-rate = <0>;
				};
				pins2 {
					pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
					bias-disable;
				};
			};	
		
			uart4_idle_pins_a: uart4-idle-0 {
				pins1 {
					pinmux = <STM32_PINMUX('G', 11, ANALOG)>; /* UART4_TX */
				};
				pins2 {
					pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
					bias-disable;
				};
			};
		
			uart4_sleep_pins_a: uart4-sleep-0 {
				pins {
					pinmux = <STM32_PINMUX('G', 11, ANALOG)>, /* UART4_TX */
						<STM32_PINMUX('B', 2, ANALOG)>; /* UART4_RX */
				};
			};
		}
	2）引用相应的配置节点
		在描述设备的节点中使用 pinctrl-n(n从0开始) 引用相应的引脚配置节点，并通过 pinctrl-names 设置相应 pinc
	trl-n 的状态名称，如下是在出口中引用引脚配置节点的示例：
		&uart4 {
			//分别指定 pinctrl-0~2 的状态为 "default", "sleep", "idle"
			pinctrl-names = "default", "sleep", "idle";
			pinctrl-0 = <&uart4_pins_a>;
			pinctrl-1 = <&uart4_sleep_pins_a>;
			pinctrl-2 = <&uart4_idle_pins_a>;
			/delete-property/dmas;
			/delete-property/dma-names;
			status = "okay";
		};
4、 pinctrl 子系统与总线设备驱动框架的关系
	在总线设备驱动框架中，调用驱动的 probe 函数之前会将设备与其引用的引脚配置节点进行绑定，并初始化 "default"
或 "init" 状态的引脚
6、 pinctrl 子系统与 gpio 子系统关系
	一般 pinctrl 子系统默认将未配置复用功能的引脚作为 GPIO ，此时可以通过 GPIO 子系统对其进行控制
